﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PlaneGame
{
    /**
     * 窗体是一个Class对象
     * 这个对象它还继承自Form这个类
     */
    public partial class MainForm : Form
    {

        public MainForm()
        {
            InitializeComponent();
            //OptimizedDoubleBuffer添加缓冲
            //AllPaintingInWmPaint 防止窗体手动闪烁
            //ResizeRedraw  当窗体大小发生改变的时候
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true);
        }

        int bgY = -850;    //背景图片初始坐标
        const int BULLET_OFFSET = 20;
        //窗体加载事件
        private void MainForm_Load(object sender, EventArgs e)
        {

            this.pictureBox1.Image = Properties.Resources.name;
            DataUtil.hero = new Hero(220, 300);   //创建真正的飞机

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawImage(Properties.Resources.background, 0, bgY);   //画背景
            DataUtil.hero.Draw(e.Graphics);  //画飞机

            try
            {
                //画玩家子弹
                for (int i = DataUtil.bulletList.Count - 1; i >= 0; i--)
                {
                    DataUtil.bulletList[i].Draw(e.Graphics);
                    switch (DataUtil.bulletList[i].Angle)
                    {
                        case 0:
                            DataUtil.bulletList[i].Y -= BULLET_OFFSET;
                            break;
                        case 60:
                            DataUtil.bulletList[i].X += (int)(BULLET_OFFSET / 2);
                            DataUtil.bulletList[i].Y -= (int)(BULLET_OFFSET * Math.Cos(Math.PI / 6));
                            break;
                        case 30:
                            DataUtil.bulletList[i].X += (int)(BULLET_OFFSET * Math.Cos(Math.PI / 6));
                            DataUtil.bulletList[i].Y -= (int)(BULLET_OFFSET / 2);
                            break;
                        case 120:
                            DataUtil.bulletList[i].X -= (int)(BULLET_OFFSET / 2);
                            DataUtil.bulletList[i].Y -= (int)(BULLET_OFFSET * Math.Cos(Math.PI / 6));
                            break;
                        case 150:
                            DataUtil.bulletList[i].X -= (int)(BULLET_OFFSET * Math.Cos(Math.PI / 6));
                            DataUtil.bulletList[i].Y -= (int)(BULLET_OFFSET / 2);
                            break;
                    }
                }
                //画敌机
                //foreach只适合于静态集合（集合不会发生改变，我们就用forEach）
                //当集合如果是动态集合的时候，我们一般都使用倒序
                for (int i = DataUtil.enemyList.Count - 1; i >= 0; i--)
                {
                    DataUtil.enemyList[i].Draw(e.Graphics);
                }


                //画道具
                for (int i = DataUtil.toolList.Count - 1; i >= 0; i--)
                {
                    DataUtil.toolList[i].Draw(e.Graphics);
                }


                //画爆炸动画
                for (int i = DataUtil.boomList.Count - 1; i >= 0; i--)
                {
                    DataUtil.boomList[i].Draw(e.Graphics);
                }

                //画得分
                e.Graphics.DrawString("得分：" + DataUtil.Score.ToString(), new Font("微软雅黑", 18), new SolidBrush(Color.Red), 10, 10);
            }
            catch (Exception)
            {

            }
           

        }

        //闹钟响了以后要做什么
        private void timer1_Tick(object sender, EventArgs e)
        {
            bgY = bgY + 5;
            if (bgY > 0)
            {
                bgY = -850;
            }
            this.Invalidate();  //重新去绘画窗体

            //判断一下当前游戏界面上面，敌人的飞机是否满足小于8架的条件
            if (DataUtil.enemyList.Count < 8)
            {
                //说明飞机不够
                int count = 8 - DataUtil.enemyList.Count;
                Random rd = new Random();  //创建一个随机数对象
                for (int i = 0; i < count; i++)
                {
                    //出现飞机概率 小飞机 85%  中飞机 10%  大飞机5%
                    int temp = rd.Next(100);  //产生一个100以内的随机数
                    int type = 0;  //默认是小飞机
                    if (temp >= 95)
                    {
                        type = 2;
                    }
                    else if (temp >= 85)
                    {
                        type = 1;
                    }
                    else
                    {
                        type = 0;
                    }

                    Enemy enemy = new Enemy(rd.Next(480), 50, type);
                    DataUtil.enemyList.Add(enemy);
                }
            }

            //检测碰撞
            checkCrash();
        }

        //重写鼠标移动的方法
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            //在这里，要控制玩家飞机的移动  改变飞机的横纵坐标就可以了
            //鼠标的坐标就是玩家飞机的坐标
            if (DataUtil.hero != null)
            {
                DataUtil.hero.X = e.X;
                DataUtil.hero.Y = e.Y;
            }
        }


        //发射子弹的定时器执行事件
        private void timer2_Tick(object sender, EventArgs e)
        {
            if (DataUtil.hero != null)
            {
                DataUtil.hero.Fire();     //发射子弹
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //如果用户没有输入昵称，则不让它开始游戏
            if (!string.IsNullOrEmpty(this.textBox1.Text.Trim()))
            {
                //启动之前设置好的两个定时器
                this.timer1.Enabled = true;
                this.timer2.Enabled = true;

                //游戏启动以后，再隐藏光标
                System.Windows.Forms.Cursor.Hide();

                //隐藏飞机大战的图标与按钮
                this.panel1.Visible = false;
            }
            else
            {
                MessageBox.Show("请输入昵称以后再开始");
            }


        }


        /// <summary>
        /// 检测两个物体是否有碰撞过程
        /// </summary>
        public void checkCrash()
        {
            //在遍历的时候，一定要考虑一种情况，就是倒序遍历
            //第一种情况：玩家飞机的子弹与敌人飞机进行了碰撞
            for (int i = DataUtil.bulletList.Count - 1; i >= 0; i--)   //子弹
            {
                for (int j = DataUtil.enemyList.Count - 1; j >= 0; j--)  //敌机
                {
                    //检测这两个对象的矩形是否有相交过程
                    Rectangle rect1 = DataUtil.bulletList[i].getRectangle();
                    Rectangle rect2 = DataUtil.enemyList[j].getRectangle();
                    if (rect1.IntersectsWith(rect2))
                    {
                        //子弹把敌机打中了
                        DataUtil.bulletList.RemoveAt(i);   //移除当前子弹
                        DataUtil.enemyList[j].IsDie();     //检测当前飞机是否死亡
                        //一颗子弹只可以使用一次，所以这颗子弹是肯定不能再和其它的敌机做碰撞检测的
                        break;
                    }
                }
            }

            //第二种情况：敌人飞机与玩家飞机的碰撞
            for (int i = DataUtil.enemyList.Count - 1; i >= 0; i--)
            {
                Rectangle rect1 = DataUtil.enemyList[i].getRectangle();  //拿到敌机的矩形
                Rectangle rect2 = DataUtil.hero.getRectangle();          //拿到玩家飞机的矩形
                //检测两个矩形是否有相交
                if (rect1.IntersectsWith(rect2))
                {
                    //游戏停止
                    this.timer1.Enabled = false;
                    this.timer2.Enabled = false;
                    System.Windows.Forms.Cursor.Show();     //重新显示鼠标的光标
                    DialogResult dr = MessageBox.Show("你挂了，是否重新开始游戏", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
                    if (dr == DialogResult.Yes)
                    {
                        //重新开始游戏
                        Application.Restart();
                    }
                    else
                    {
                        //用户不想重新开始游戏，那么，我们就打开结果窗体
                        ResultForm result = new ResultForm();
                        result.Show();
                        this.Hide();
                        return;
                    }
                }
            }

            //第三种情况：玩家飞机得到了道具
            for (int i = DataUtil.toolList.Count - 1; i >= 0; i--)
            {
                Rectangle rect1 = DataUtil.toolList[i].getRectangle();  //拿到道具的矩形
                Rectangle rect2 = DataUtil.hero.getRectangle();          //拿到玩家飞机的矩形
                                                                         //检测两个矩形是否有相交
                if (rect1.IntersectsWith(rect2))
                {
                    DataUtil.toolList[i].IsGet();     //当前飞机是否得到道具
                    DataUtil.toolList.RemoveAt(i);   //移除当前道具   
                    DataUtil.IsManyBullet = true;  
                    break;
                }
            }
        }


        private void Timer3_Tick_1(object sender, EventArgs e)
        {
            Random rd = new Random();  //创建一个随机数对象
            Tools tools = new Tools(rd.Next(480), 50);
            DataUtil.toolList.Add(tools);
        }
    }
}
